#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DuLink.h"  
#include "Stack.h"

// 搜索文本
int Search_Text(DuLinkList *L,Elemtype text)
{
    int i = 1;                      
    int count=0;                   
    DuLinkList p = (*L)->next;      
    
    while (p)
    {
        // 检查当前行是否包含要搜索的文本
        if (p->info != NULL && strstr(p->info, text) != NULL)
        {
            char *str = p->info;    
            int len = 0;            
            
            // 在当前行中查找所有匹配项
            while (str != NULL && strstr(str, text) != NULL)
            {
                count++;                                    
                char *found_pos = strstr(str, text);        
                int column = found_pos - str;              
                len = len + column + 1; 
                // 输出找到的位置信息
                printf("Found at line %d, position %d, this count is %d\n", i, len, count);
                printf("Text: %s\n", p->info);
                str = found_pos + strlen(text);             
                len = len + strlen(text) - 1;  
                if (*str == '\0')                           
                {
                    break;
                }
            }
        }
        i++;                        
        p = p->next;               
    }

    if(count==0)
    {
        printf("can't find\n");
        return 0;
    }    
    else
    {
        return count;
    }    
}


void Replace_text(DuLinkList *L, Elemtype old_text, Elemtype new_text, PLinkStack undoStack, PLinkStack redoStack)
{
    while (1)
    {
        // 提示用户输入要替换的行号
        printf("Enter line number to replace or if you want to exit,please Enter -1:");
        int line;
        scanf("%d", &line);
        while(getchar() != '\n'); 
        
        if(line == -1)              // 用户选择退出
            break;
        
        // 定位到指定行
        int i = 1;
        DuLinkList p = (*L)->next;
        while (i < line && p != NULL) 
        {
            i++;
            p = p->next;
        }
        
        if (p == NULL || i != line) 
        {
            printf("Line %d not found!\n", line);
            continue;  
        }
        
        // 检查该行是否包含要替换的文本
        if(p->info != NULL && strstr(p->info, old_text) != NULL)
        {
            Elemtype str = p->info;             
            int replace_count = 0;              
            int old_length = strlen(old_text);  
            
            Elemtype current_str = strdup(str);
            if (current_str == NULL) 
            {
                printf("Memory allocation failed!\n");
                continue;
            }
            
            // 循环替换该行中的文本
            while (1)
            {
               
                printf("Enter startpos number to replace:");
                int pos;
                scanf("%d", &pos);
                while(getchar() != '\n');
                
                
                if(pos < 1 || pos > strlen(current_str)) 
                {
                    printf("Invalid position!\n");
                    continue;
                } 
                
                // 检查指定位置是否匹配要替换的文本
                if (strncmp(current_str + pos - 1, old_text, old_length) != 0) 
                {
                    printf("Text not found at position %d!\n", pos);
                    continue;
                }
                
                // 执行文本替换操作
                int str_len = strlen(current_str);
                int new_length = strlen(new_text);
                char *result = (char*)malloc(str_len - old_length + new_length + 1);
                strncpy(result, current_str, pos-1);
                result[pos-1] = '\0';
                strcat(result, new_text);
                strcat(result, current_str + pos-1 + old_length);
                char *old_str_before_replace = strdup(current_str);
                free(current_str);
                current_str = result;
                replace_count++;
                
                // 显示替换结果
                printf("replace Successful (count: %d)\n", replace_count);
                printf("New text: %s\n", current_str);
                
                // 查找剩余匹配项
                printf("Searching for remaining occurrences in current text...\n");
                int count = 0;
                char *search_str = current_str;
                while (search_str != NULL && strstr(search_str, old_text) != NULL)
                {
                    count++;
                    char *found_pos = strstr(search_str, old_text);
                    int position = found_pos - current_str + 1;
                    printf("Found at position %d, this count is %d\n", position, count);
                    search_str = found_pos + strlen(old_text);
                    if (*search_str == '\0') 
                    {
                        break;
                    }
                }
                
                // 检查是否还有匹配项
                if(count == 0)
                {
                    printf("No more text to replace.\n");
                    break;
                }
                
                // 将操作记录到撤销栈中
                EditAction *action = malloc(sizeof(EditAction));
                if (!action) 
                {
                    fprintf(stderr, "Memory allocation failed for undo action\n");
                    break;
                }
                action->operation = 'R';            // 替换操作
                action->line = line;                // 行号
                action->pos=0;                      // 位置
                action->oldText = old_str_before_replace;
                action->newText = strdup(current_str);
                Push_LinkStack(undoStack, action);  // 入撤销栈
                destroyStack_link(redoStack);       // 清空重做栈
                
                // 询问用户是否继续替换
                printf("if you want to stop, please Enter -1, else Enter other number: ");
                int choice;
                scanf("%d", &choice);
                while(getchar() != '\n');

                if(choice == -1) 
                {
                    break;
                }
            }
            
            // 更新链表中的文本
            free(p->info);
            p->info = strdup(current_str);
            free(current_str);
        }
        else
        {
            printf("Line %d does not contain the text to replace.\n", line);
        }
    }
}

//寻找用户要复制的文本
Elemtype  Copy_DL(DuLinkList *L,int line,int pos,int length)
{
    if (line < 1 || pos < 1 || length <= 0)
    {
        printf("Invalid parameters!\n");
        return NULL;
    }

    int i = 1;
    DuLinkList p = (*L)->next;
    // 循环找到指定行
    while (p)
    {
        if(i==line)
        {
            Elemtype str = p->info;         // 当前行文本
            if (!str)
            {
                printf("Line %d is empty\n", line);
                return NULL;
            }
            int str_len = strlen(str);      
            if (pos > str_len)
            {
                printf("Position out of range!\n");
                return NULL;
            }
            if (pos + length -1> str_len)
            {
                length = str_len - pos+1;
            }

            Elemtype copy_text = (Elemtype)malloc(length + 1);
            if (!copy_text)
            {
                printf("Memory allocation failed!\n");
                return NULL;
            }
            strncpy(copy_text, str + pos-1, length);
            copy_text[length] = '\0'; 
            printf("Copied text: %s\n", copy_text);
            return copy_text;
        }
        i++;
        p = p->next;
    }

    printf("Line out of range!\n");
    return NULL;
}

//把文本粘贴到指定行指定位置
void Paste_DL(DuLinkList *L, int line, int startups, Elemtype paste_text)
{
    // 验证参数
    if (line < 1) 
    {
        printf("Invalid line!\n");
        return;
    }
    if (startups < 1)
    {
        printf("Invalid position!\n");
        return;
    }
    if(!paste_text)
    {
        printf("Paste Text is Empty!\n");
        return;
    }
    
    int i = 1;
    DuLinkList p = (*L)->next;
    // 定位到指定行
    while (p)
    {
        if (i == line)
        {
            int pos = startups;
            char *str = p->info;        
            if(!str)
            {
                printf("This Line of Link is Empty!\n");
                return;
            }
            int len_str = strlen(str); 

            if (pos > len_str + 1)
            {
                printf("Error: position out of range\n");
                return;
            }
            
            int len_paste = strlen(paste_text) ;
            char *result = (char*)malloc(len_str + len_paste + 1);
            if (result == NULL)
            {
                printf("Memory allocation failed!\n");
                return;
            }
            if (pos > 1)
                strncpy(result, str, pos - 1);
            result[pos - 1] = '\0';

            if (len_paste > 0)
                strcat(result, paste_text);

            strcat(result, str + pos - 1);

            if (p->info)
                free(p->info);
            p->info = result;

            printf("paste Successed\n");
            return;
        }
        i++;
        p = p->next;
    }

    printf("Line out of range!\n");
}

// 删除要剪切的文本
Elemtype Delete_cut(DuLinkList *L,int line,int pos,int length)
{
    if (line < 1 || pos < 1 || length <= 0)
    {
        printf("Invalid parameters!\n");
        return NULL;
    }

    int i = 1;
    DuLinkList p = (*L)->next;
    while (p)
    {   
        if(i==line)
        {
            Elemtype str = p->info;        
            if (!str)
            {
                printf("Line %d is empty\n", line);
                return NULL;
            }
            int str_len = strlen(str);      
            if (pos > str_len)
            {
                printf("Position out of range!\n");
                return NULL;
            }
            if (pos + length -1> str_len)
            {
                length = str_len - pos+1;
            }

            Elemtype copy_text = (Elemtype)malloc(length + 1);
            if (!copy_text)
            {
                printf("Memory allocation failed!\n");
                return NULL;
            }
            
            strncpy(copy_text, str + pos-1, length);
            char *result = (char*)malloc(str_len - length + 1);
            strncpy(result, str, pos-1);
            result[pos-1] = '\0';
            strcat(result, str + pos-1 + length);
            copy_text[length] = '\0'; 
            printf("Cut text: %s\n", copy_text);
            p->info = result;              
            return copy_text;
        }
        i++;
        p = p->next;
    }

    printf("Line out of range!\n");
    return NULL;
}